/****************************************************************************
 *
 * Copyright (C) 2003-2008 Los Alamos National Security, LLC
 *                         Packet Analytics Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License Version 2 as
 * published by the Free Software Foundation.  You may not use, modify or
 * distribute this program under any other version of the GNU General
 * Public License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 ****************************************************************************/
package nfse;

import java.util.*;
import java.sql.*;

/*********
 * This class is run by NetFSEServer and starts threads to monitor datafiles for
 * new records. It runs indefinitely, periodically checking the state of the
 * app_list database table to find new entries.
 * 
 * Does not currently handle the case where a DataFileMonitor is removed. Only a
 * system restart will correct this.
 * 
 * @author bduphoff
 * 
 */

public class DataFileMonitorLauncher extends Thread {

    protected class TypeAppPair implements Comparable<TypeAppPair> {
        int typeID = -1;

        int appID = -1;

        public int compareTo(TypeAppPair o) {
            if (typeID == o.typeID && appID == o.appID)
                return 0;
            return -1;
        }

        public boolean equals(Object o) {
            if (!(o instanceof TypeAppPair))
                return false;
            TypeAppPair pair = (TypeAppPair)o;
            int val = pair.compareTo(this);
            if (val == 0)
                return true;
            return false;
        }

        public String toString() {
            return "TypeAppPair: " + super.toString() + ", " + typeID + ", " + appID;
        }

        public int hashCode() {
            return (typeID + "," + appID).hashCode();
        }
    }

    private HashMap<TypeAppPair, DataFileMonitor> dataFileMonitors = new HashMap<TypeAppPair, DataFileMonitor>();

    /******************
     * Runs forever, periodically checks to see if new configuration information
     * has been added. If so, starts new DataFileMonitor.
     */
    public void run() {
        try {
            MetaDatabase mdb = MetaDatabase.create();
            while (true) {
                Statement s = mdb.createStatement();

                // System.out.println("Listing pairs...");
                // for (TypeAppPair pair: dataFileMonitors.keySet()) {
                // System.out.println(pair);
                // }

                // Create a list of appIDs based on the app_list table
                Vector<Integer> appIDs = new Vector<Integer>();
                String sql = "select * from app_list";
                ResultSet rs = s.executeQuery(sql);
                while (rs.next()) {
                    appIDs.addElement(rs.getInt("App_ID"));
                }
                rs.close();

                // For each type, find DataFileMonitors and start them
                sql = "select * from type_classes";
                rs = s.executeQuery(sql);
                while (rs.next()) {
                    int typeID = rs.getInt("type_id");
                    for (int x = 0; x < appIDs.size(); x++) {
                        int appID = appIDs.elementAt(x);
                        TypeAppPair pair = new TypeAppPair();
                        pair.typeID = typeID;
                        pair.appID = appID;
                        DataFileMonitor mon = dataFileMonitors.get(pair);
                        if (mon == null) {
                            System.out.println("Starting Data File Monitor for type " + typeID + ", app " + appID);
                            mon = new DataFileMonitor(typeID, appID);
                            dataFileMonitors.put(pair, mon);
                            mon.start();
                        }
                    }
                }
                rs.close();
                s.close();

                // Sleep for a minute
                Thread.sleep(60 * 1000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}